﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using ThePresenter.ViewModel;
using System.ComponentModel;

namespace ThePresenter.Network
{
	class Server : ViewModelBase
	{
		private TcpListener _Listener;

		private ServerState _State;

		public ServerState State
		{
			get {
				return this._State;
			}
			private set 
			{
				if (this._State != value)
				{
					this._State = value;
					OnPropertyChanged("State");
				}
			}
		}

		public String StateText
		{
			get;
			set;
		}

		public BindingList<String> Clients
		{
			get;
			private set;
		}

		public Server(int port)
		{
			this.Clients = new BindingList<string>();
			
			// HACK
			this.Clients.Add("Dummy client1");
			this.Clients.Add("Dummy client2");
			this.Clients.Add("Dummy client3");

			this._Listener = new TcpListener(IPAddress.Any, port);
			this.State = ServerState.CREATED;
		}

		public void AddClientPH(String s)
		{
			this.Clients.Add(s);
		}

		/// <summary>
		/// Callback method for BeginAccept() method 
		/// </summary>
		/// <param name="Result">Accept result</param>
		private void OnClientConnect(IAsyncResult Result)
		{
			//try
			//{
			//    // Get new socket for incoming connection
			//    Socket AcceptedSocket =  this._ListeningSocket.EndAccept(Result);
			//    _D.Write(Resources.ReceivedNewSocketFrom, AcceptedSocket.RemoteEndPoint.ToString());

			//    // Add socket to clients
			//    Client C = new Client(AcceptedSocket);
			//    this._Clients.Add(C);

			//    if (this.ClientAdded != null) this.ClientAdded(this, C.LocalId);

			//    C.IncomingData += new Client.ClientIncomingDataHandler(Client_IncomingData);
			//    C.Start();

			//    _D.Write(Resources.WaitingForDataFrom, AcceptedSocket.RemoteEndPoint.ToString());

			//    // Fire IncomingConnection event
			//    // if (this.IncomingConnection != null) IncomingConnection(this, AcceptedSocket);
			//}
			//catch (Exception E)
			//{
			//    _D.Write("NetComServer.OnClientConnect()\nThere was error handling incoming connection: {0}", E.Message);
			//}
			//finally
			//{
			//    try
			//    {
			//        // Begin listening for more
			//        this._ListeningSocket.BeginAccept(this.OnClientConnect, null);
			//        _D.Write(Resources.WaitingForConnections);
			//    }
			//    catch (Exception E)
			//    {
			//        DebugClass.ShowMessage("NetComServer.OnClientConnect()\nThere was error trying to accept new connections: {0}", E.Message);
			//    }
			//}
		}

		public void Start()
		{
			_Listener.Start();
			_Listener.BeginAcceptTcpClient(OnClientConnect, _Listener);

			this.State = ServerState.STARTED;
			this.StateText = String.Format("Accepting connections on {0}:{1}", ((IPEndPoint)_Listener.Server.LocalEndPoint).Address.ToString(), ((IPEndPoint)_Listener.Server.LocalEndPoint).Port);
			this.OnPropertyChanged("StateText");
		}

		public void Stop()
		{
			_Listener.Stop();

			this.State = ServerState.STOPPED;
			this.StateText = String.Format("Not accepting connections");
			this.OnPropertyChanged("StateText");
		}
	}

	enum ServerState
	{ 
		CREATED = 0,
		STARTED,
		STOPPED
	}
}
